﻿//  --------------------------------
//  Copyright (c) Microsoft Corporation. All rights reserved.
//  This source code is made available under the terms of the Microsoft Public License (Ms-PL)
//  http://www.codeplex.com/oxite/license
//  ---------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.DirectoryServices.AccountManagement;
using Oxite.Infrastructure;
using Oxite.Models;
using Oxite.Extensions;
using ECube.SEC.Models;
using ECube.SEC.Services;
using ECube.SEC.Membership.Services;
using ECube.SEC.Membership.Models;
using ECube.SEC.FormsAuthentication.Services;

namespace ECube.SEC.FormsAuthentication.Extensions
{
    public static class IUserServiceExtensions
    {
        public static User GetUser(this IUserService userService, string name, string password)
        {
            return GetUser(userService, name, password,null);
        }
        public static User GetUser(this IUserService userService, string name, string password,string loginTo)
        {   
            
            User user;      
            if (string.IsNullOrEmpty(loginTo))
            {
                user = userService.GetUser(name);

                if (user != null)
                {
                    string data = userService.GetModuleData(user, "FormsAuthentication");

                    if (data != null)
                    {
                        string[] splitData = data.Split('|');

                        if (splitData.Length != 2) throw new InvalidOperationException("Password and PasswordSalt could not be read from module data");

                        string userPasswordSalt = splitData[0];
                        string userPassword = splitData[1];

                        if (userPassword == password.SaltAndHash(userPasswordSalt))
                            return user;
                    }
                }     
            }
            else
            {
                loginTo = loginTo.ToLower();
            
                    ADConnect connect = userService.GetADConnects().Where(c => c.Key.Equals(loginTo)).FirstOrDefault();
                    if (connect != null)
                    {
                        IADAuthenticationUserService adService = ADAuthenticationUserService.GetInstance(connect);
                        UserPrincipal up = adService.Valite(name, password);
                        if (up != null)  //如果用户通过AD验证
                        {
                           

                            
                                
                           List<GroupPrincipal> adGroups = up.GetAuthorizationGroups().Where(p=>p is GroupPrincipal).Select(p=>p as GroupPrincipal).ToList();

                            List<ADGroup> usrGroups = new List<ADGroup>();
                            List<ADGroup> groups = userService.GetADGroups(loginTo).ToList();
                            foreach (Principal p in adGroups)
                            {
                                ADGroup ag = groups.Where(g => g.Name.Equals(p.SamAccountName)).FirstOrDefault();
                                if(ag != null)
                                {
                                    usrGroups.Add(ag);  
                                }
                            }
                            
                            user = userService.GetADUsers(loginTo).Where(u=>u.Name.Equals(name)).FirstOrDefault();  //检查本地表中是否存在本用户。
                            if (user == null)
                            {
                                if (usrGroups.Count == 0)
                                {
                                    return null;
                                }
                                user = new User(up.SamAccountName, up.DisplayName, "AD",loginTo,up.EmailAddress, up.EmailAddress.ComputeHash(), EntityState.Normal);

                            }                            
                            user.AuthenticationValues.Add("ADGroups", usrGroups);

                            return user;
                               
                        }
                    }
            }

            return null;
        }
    }
}
